#include <net_util/http_util.h>
#include "ssicloud_vs_feedback.h"

using namespace ssicloud;
VSFeedback::VSFeedback()
    : ItemObject<EmptyInfoNode>(LQ_BASE_URL "/vs/feedback/upload"
                           , OBJECT_NAME_VSFeedback
                           , NetUrl::NET_HTTP_METHOD_POST_MULTI)
    , m_readHandler(NULL)
{
    // mUrl.appendHeader(HEADER_MULTI); // 表示传输文件
    // mUrl.appendHeader(HEADER_JSON);
    mUrl.appendHeader(HEADER_TOKEN);

    mUrl.append("vin", VIN_STRING);
}

VSFeedback::~VSFeedback()
{
    fname.clear();
    uploadTime.clear();
}

bool VSFeedback::postEventInfo(FeedbackIn &in)
{
    if (isLoading()) {
        GEN_Printf(LOG_WARN, "current is loading.");
        return false;
    }

    if (m_readHandler) delete m_readHandler;

    if (in.type == 1) {
        ReadFile *f = new ReadFile;
        if (!f->openFile(in.file)) return false;
        m_readHandler = f;
    } else if (in.type == 2)
    {
        ContentFile *f = new ContentFile;
        if (!f->openContent(in.content)) return false;
        m_readHandler = f;
    } else {
        GEN_Printf(LOG_ERROR, "input type not unkown.");
        return false;
    }

    fname.clear();
    uploadTime.clear();
    HttpUtil::urlEncoding(ByteString(in.fname.data(), in.fname.size()), fname);
    HttpUtil::urlEncoding(ByteString(in.uploadTime.data(), in.uploadTime.size()), uploadTime);

    //fname.swap(in.fname);
    fphone.swap(in.fphone);
    type = SFString::number(in.type); // 1语音2文字
    feedbackType = SFString::number(in.feedbackType);
    //file.swap(in.file);
    //content.swap(in.content);
    //uploadTime.swap(in.uploadTime);

    mUrl.appendChange("fname",        fname.c_str());
    mUrl.appendChange("fphone",       fphone.c_str());
//    mUrl.appendChange("type",         type.c_str());
    mUrl.appendChange("feedbackType", feedbackType.c_str());
    //mUrl.appendChange("file",         file.c_str());
    //mUrl.appendChange("content",      content.c_str());
    mUrl.appendChange("uploadTime",   uploadTime.c_str());

    // 设置读取数据的回调
    mUrl.setReadHandler(m_readHandler);

    return obtain();
}

bool VSFeedback::postEventInfo2(FeedbackIn2 &in)
{
    if (isLoading()) {
        GEN_Printf(LOG_WARN, "current is loading.");
        return false;
    }

    if (m_readHandler) delete m_readHandler;

    if (in.feedbackMode == 1) {
        ReadFile *f = new ReadFile;
        if (!f->openFile(in.file)) return false;
        m_readHandler = f;
    } else if (in.feedbackMode == 2)
    {
        ContentFile *f = new ContentFile;
        if (!f->openContent(in.feedbackContent)) return false;
        m_readHandler = f;
    } else {
        GEN_Printf(LOG_ERROR, "input type not unkown.");
        return false;
    }

    fname.clear();
    uploadTime.clear();
    HttpUtil::urlEncoding(ByteString(in.name.data(), in.name.size()), fname);
    HttpUtil::urlEncoding(ByteString(in.feedbackCreateDate.data(), in.feedbackCreateDate.size()), uploadTime);

    //fname.swap(in.fname);
    fphone.swap(in.phone);
    feedbackType = SFString::number(in.feedbackType); // 1语音2文字
    feedbackMode = SFString::number(in.feedbackMode);
    //file.swap(in.file);
    //content.swap(in.content);
    //uploadTime.swap(in.uploadTime);

    mUrl.appendChange("name",        fname.c_str());
    mUrl.appendChange("phone",       fphone.c_str());
    mUrl.appendChange("feedbackType", feedbackType.c_str());
    mUrl.appendChange("feedbackMode",         feedbackMode.c_str());
    mUrl.appendChange("feedbackCreateDate",   uploadTime.c_str());

    // 设置读取数据的回调
    mUrl.setReadHandler(m_readHandler);

    return obtain();
}

int VSFeedback::genResult(NetBuffer *data)
{
    int ret = KL_DATA_PRISER_OK;
    GEN_Printf(LOG_DEBUG, "size: %lu\n%s", data->size(), (char *)data->buffer());
    cJSON *root = cJSON_Parse((char *)data->buffer(), data->size());
    cJSON *code = cJSON_GetObjectItem(root, "code");
    if (code && *(code->valuestring) == '1')
    {
        // cJSON_GetStringValue()
        // GEN_Printf(LOG_DEBUG, "code value = %d, %s", (int)code->valuedouble);
        GEN_Printf(LOG_INFO, "upload info successfully.");
    } else
    {
        GEN_Printf(LOG_ERROR, "priser failed, size: %lu\n%s", data->size(), data->buffer());
        ret = KL_DATA_PRISER_JSOC_ERROR;
    }

    cJSON_Delete(root);
    return ret;
}

void VSFeedback::profile()
{

}


bool VSFeedback::ReadFile::openFile(SFString &fn)
{
    filename.swap(fn);
    fd = ::open(filename.c_str(), O_RDONLY);
    if (fd < 0)
    {
        GEN_Printf(LOG_ERROR, "open failed: %s.", strerror(errno));
        return false;
    }

    struct stat st;
    if (fstat(fd, &st))
    {
        GEN_Printf(LOG_ERROR, "fstat failed: %s.", strerror(errno));
        return false;
    }

    cur   = 0;
    total = st.st_size;

    return true;
}

VSFeedback::ReadFile::~ReadFile() {
    if (fd > 0) ::close(fd);
}

unsigned int VSFeedback::ReadFile::getSize() {
    return total;
}

int VSFeedback::ReadFile::read(char *data, int size)
{
    return ::read(fd, data, size);
}

const char *VSFeedback::ReadFile::getBaseName(){
    return rindex(filename.c_str(), '/');
}

bool VSFeedback::ContentFile::openContent(SFString &ct)
{
    content.swap(ct);
    cur = 0;
    total = content.size();
    GEN_Printf(LOG_INFO, "open content: %d", total);

    return !content.empty();
}

unsigned int VSFeedback::ContentFile::getSize()
{
    return total;
}

int VSFeedback::ContentFile::read(char *data, int size)
{
    int lase   = total - cur;

    if (lase > 0)
    {
        int cpsize = size > lase ? lase : size;
        memcpy(data, content.data() + cur, cpsize);
        cur += cpsize;
        return cpsize;
    } else
    {
        return 0;
    }
}

const char *VSFeedback::ContentFile::getBaseName()
{
    return "feedbackContent";
}
